<template>
  <view class="my-settle-container">
     <!-- 结算组件 -->
      <!-- 全选区域开始 -->
      <!-- @click="changeAllState"全选/反选radio影响所有商品勾选状态-->
       <label class="radio" @click="changeAllState">
         <!-- :checked="isFullCheck"是否全选(`购物车里面所以商品的勾选项`影响`结算模块里面的全选项`) -->
          <radio color="#C00000" :checked="isFullCheck" /><text>全选</text>
       </label>
      <!-- 全选区域结束 -->
      
       <!-- 合计区域开始 -->
       <view class="amount-box">
         <!-- 这里同样是直接使用vuex的计算属性；不需要使用watch监听器将vuex计算属性赋给别的变量 -->
           合计:<text class="amount">￥{{checkedGoodsAmount}}</text>
        </view>
       <!-- 合计区域结束 -->
       
       <!-- 结算按钮开始 -->
       <!-- 这里不需要将``vuex计算属性``赋值给组件的info徽标属性和tabbar的uni.setTabBarBadgeapi设置text属性；这里是``直接使用checkedCount这个vuex的计算属性``所以不需要watch监听器去``动态执行vuex的计算属性变化`` -->
       <!-- 结算按钮绑定点击事件处理函数@click="settlement" -->
        <view class="btn-settle" @click="settlement">结算({{checkedCount}})</view>
       <!-- 结算按钮结束 -->
  </view>
</template>

<script>
  // 通过 mapGetters 辅助函数，将需要的 getters 映射到当前组件中使用
  import { mapGetters, mapMutations, mapState } from 'vuex'
  export default {
    name:"my-settle",
    data() {
      return {
        // 倒计时的秒数
        seconds: 3,
        // 定时器的 Id
        timer: null
        
      };gett
    },
    computed:{
      // 将勾选的商品的总数量checkedCount;动态统计购物车中商品的总数量(勾选+未勾选)total；已勾选的商品的总价checkedGoodsAmount；通过辅助函数映射过来
      ...mapGetters('m_cart', ['checkedCount','total','checkedGoodsAmount']),
     // addstr 是详细的收货地址
      ...mapGetters('m_user', ['addstr']),
     // token 是用户登录成功之后的 token 字符串
      ...mapState('m_user', ['token']),
      // 映射购物车state中的 购物车的数组，用来存储购物车中每个商品的信息对象(方便下方筛选必要的数据传递给后端)
      ...mapState('m_cart',['cart']),
      // 是否全选(`购物车里面所以商品的勾选项`影响`结算模块里面的全选项`)
      isFullCheck(){
        return this.total === this.checkedCount
      }
    },
    methods:{
      // 使用 mapMutations 辅助函数，把 m_cart 模块提供的 updateAllGoodsState 方法映射到当前组件中使用
      // vuex里面``更新所有商品的勾选状态方法``(全选/反选radio影响所有商品勾选状态)
      ...mapMutations('m_cart', ['updateAllGoodsState']),
       // 把 m_user 模块中的``更新重定向的信息对象方法``updateRedirectInfo 方法映射到当前页面中使用
      ...mapMutations('m_user', ['updateRedirectInfo']),
       changeAllState() {
         // 修改购物车中所有商品的选中状态
         // !this.isFullCheck 表示：当前全选按钮的状态``取反之后，就是最新的勾选状态``(一定要取反;因为你点击了呀)
         this.updateAllGoodsState(!this.isFullCheck)
       },
       // 点击了结算按钮
       settlement() {
          // 1. 先判断是否勾选了要结算的商品
           if (!this.checkedCount) return uni.$showMsg('请选择要结算的商品！')
           
          // 2. 再判断用户是否选择了收货地址
          if (!this.addstr) return uni.$showMsg('请选择收货地址！')
          
          // 3. 最后判断用户是否登录了
          // if (!this.token) return uni.$showMsg('请先登录！')
          // 3. 最后判断用户是否登录了，如果没有登录，则调用 delayNavigate() 进行倒计时的导航跳转
          if(!this.token) return this.delayNavigate()
          
           // 4. 实现微信支付功能
            this.payOrder()
       },
       // 展示倒计时的提示消息
       showTips(n){
          // 调用 uni.showToast() 方法，展示提示消息
          uni.showToast({
            // 不展示任何图标
            icon: 'none',
            // 提示的消息
            title: '请登录后再结算！' + n + ' 秒后自动跳转到登录页',
            // 为页面添加``透明遮罩层``，防止点击穿透(包括tabbar此时也点不了)
            mask: true,
            // 1.5 秒后自动消失
            duration: 1500
          })
       },
       // 延迟导航到 my 页面
       delayNavigate() {
          // 把 data 中的秒数重置成 3 秒
          // (跳转了my的登录组件但是又点击tabbar回购物车页面就会有问题)
          // 所以每次触发事件；先将倒计时重置为3就不会有这样的问题
           this.seconds = 3
         // 1. 展示提示消息，此时 seconds 的值等于 3
         this.showTips(this.seconds)
         // 2. 创建定时器，每隔 1 秒执行一次
         // 将定时器的 Id 存储到 timer 中
         this.timer = setInterval(() => {
           // 2.1 先让秒数自减 1
            this.seconds--
            
           // 判断秒数是否 <= 0
           if(this.seconds<=0){
             // 清除定时器
             clearInterval(this.timer)
             // 跳转到my页面
             uni.switchTab({
               url:'/pages/my/my',
                // ``页面跳转成功之后的回调函数``(注意这个方法有成功回调)
                 success: () => {
                   // 调用 vuex 的 updateRedirectInfo 方法，把跳转信息存储到 Store 中
                   this.updateRedirectInfo({
                     // 跳转(跳转回来)的方式
                     openType: 'switchTab',
                     // 从哪个页面跳转过去的
                     from: '/pages/cart/cart'
                   })
                 }
             })
             // 终止后续代码的运行（当秒数为 0 时，不再展示 toast 提示消息）
             return
           }
          
          // 2.2 再根据最新的秒数，进行消息提示
           this.showTips(this.seconds)
         },1000)
       },
       // 微信支付方法
       async payOrder() {
          // 1. 创建订单
          // 1.1 组织订单的信息对象
           const orderInfo = {
             // 开发期间，注释掉真实的订单价格，
             // order_price: this.checkedGoodsAmount,
             // 写死订单总价为 1 分钱
             order_price: 0.01,
             consignee_addr: this.addstr,
             // 先筛选勾选商品；再返回后端需要的goods属性对象格式(原本前端定义6个数据；但是后端不需要返回这么多)
             goods: this.cart.filter(x => x.goods_state).map(x => ({ goods_id: x.goods_id, goods_number: x.goods_count, goods_price: x.goods_price }))
           }
           // 1.2 发起请求创建订单（传入`组织订单的信息对象`）
             const { data: res } = await uni.$http.post('/api/public/v1/my/orders/create', orderInfo)
             if (res.meta.status !== 200) return uni.$showMsg('创建订单失败！')
          // 1.3 得到服务器响应的“订单编号”
            const orderNumber = res.message.order_number
            
          // 2. 订单预支付(根据第一步拿到的“订单编号”重新发起请求)
          // 2.1 发起请求获取订单的支付信息
           const { data: res2 } = await uni.$http.post('/api/public/v1/my/orders/req_unifiedorder', { order_number: orderNumber })
          // 2.2 预付订单生成失败
          if (res2.meta.status !== 200) return uni.$showError('预付订单生成失败！')
          // 2.3 得到订单支付相关的必要参数("订单预支付对象")
          const payInfo = res2.message.pay
            
          // 3. 发起微信支付(把第二部获得"订单预支付对象"传递给requestPayment()方法)
          // 3.1 调用 uni.requestPayment() 发起微信支付
          const [err, succ] = await uni.requestPayment(payInfo)
          // 3.2 未完成支付
          if (err) return uni.$showMsg('订单未支付！')
          // 3.3 完成了支付，进一步查询支付的结果
          const { data: res3 } = await uni.$http.post('/api/public/v1/my/orders/chkOrder', { order_number: orderNumber })
          // 3.4 检测到订单未支付(如果我们点击状态框（确认/取消）；点击取消就会弹出订单未支付提示)
             if (res3.meta.status !== 200) return uni.$showMsg('订单未支付！')
         // 3.5 检测到订单支付完成(成功提示)
            uni.showToast({
              title: '支付完成！',
              icon: 'success'
            })
       }
    }
  }
</script>

<style lang="scss">
  .my-settle-container {
    /* 底部固定定位 */
    z-index: 9999999999999;
    position: fixed;
     bottom: 0;
     left: 0;
     width: 100%;
     height: 50px;
     // 将背景色从 cyan 改为 white
     background-color: white;
     display: flex;
     justify-content: space-between;
     align-items: center;
     padding-left: 5px;
     font-size: 14px;
     // 全选区域开始
     .radio {
         display: flex;
         align-items: center;
       }
    // 全选区域结束
  
    // 合计区域开始
       .amount {
         color: #c00000;
       }
   // 合计区域结束
  
    // 结算按钮开始
       .btn-settle {
         height: 50px;
         min-width: 100px;
         background-color: #c00000;
         color: white;
         line-height: 50px;
         text-align: center;
         padding: 0 10px;
       }
    // 结算按钮结束
  }

</style>